package com.sfy.mallchat.common.common.service;

import com.sfy.mallchat.common.common.exception.BusinessException;
import com.sfy.mallchat.common.common.exception.CommonErrorEnum;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

@Component
public class LockService {

    @Autowired
    private RedissonClient redissonClient;

    public <T> T excuteWithLock(String key, int waitTime, TimeUnit unit, Supplier<T> supplier) throws Throwable {
        RLock lock = redissonClient.getLock(key);
        boolean isTrue = lock.tryLock(waitTime,unit);
        if(!isTrue){
            throw new BusinessException(CommonErrorEnum.LOCK_LIMIT);
        }
        try{
            return supplier.get();
        }finally {
            lock.unlock();
        }
    }


    public <T> T excuteWithLock(String key,  Supplier<T> supplier) throws Throwable {
       return excuteWithLock(key,-1,TimeUnit.MICROSECONDS,supplier);
    }

    public interface Supplier<T> {
        T get() throws Throwable;
    }
}
